window.eel = {
  _host: window.location.origin,

  // These get dynamically added by library when file is served
  _py_functions: ["pick_file", "get_image", "getLog"],
  _start_geometry: { default: { size: [1280, 800], position: null }, pages: {} },

  _exposed_functions: {},

  _mock_queue: [],
  wsOpened: false,
  _mock_py_functions: function() {
    for (let i = 0; i < window.eel._py_functions.length; i++) {
      let name = window.eel._py_functions[i]
      eel[name] = function() {
        let call_object = window.eel._call_object(name, arguments)
        window.eel._mock_queue.push(call_object)
        return new Promise(function(resolve) {
          window.eel._call_return_callbacks[call_object.call] = resolve
        })
      }
    }
  },

  _import_py_function: function(name) {
    let func_name = name
    eel[name] = function() {
      let call_object = window.eel._call_object(func_name, arguments)
      window.eel._websocket.send(window.eel._toJSON(call_object))
      return new Promise(function(resolve) {
        window.eel._call_return_callbacks[call_object.call] = resolve
      })
    }
  },

  run_py: function(obj_name, fun_name, args) {
    let arg_array = []
    if (args) {
      for (let i = 0; i < args.length; i++) {
        arg_array.push(args[i])
      }
    }
    let call_id = (eel._call_number += 1)
    let _run_py_call_object = {
      call: call_id,
      obj_name: obj_name,
      fun_name: fun_name,
      args: arg_array
    }
    eel._websocket.send(eel._toJSON(_run_py_call_object))
    return new Promise(function(resolve) {
      eel._call_return_callbacks[_run_py_call_object.call] = resolve
    })
  },
  _call_number: 0,

  _call_return_callbacks: {},

  _call_object: function(name, args) {
    let arg_array = []
    for (let i = 0; i < args.length; i++) {
      arg_array.push(args[i])
    }

    let call_id = (eel._call_number += 1) + Math.random()
    return { call: call_id, name: name, args: arg_array }
  },

  _sleep: function(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms))
  },

  _toJSON: function(obj) {
    return JSON.stringify(obj, (k, v) => (v === undefined ? null : v))
  },

  _call_return: function(call) {
    return function(callback = null) {
      // console.log("callback:",callback);
      if (callback != null) {
        window.eel._call_return_callbacks[call.call] = callback
      } else {
        // console.log("_call_return_callbacks:",window.eel._call_return_callbacks);
        return new Promise(function(resolve) {
          window.eel._call_return_callbacks[call.call] = resolve
        })
      }
    }
  },

  _position_window: function(page) {
    let size = window.eel._start_geometry["default"].size
    let position = window.eel._start_geometry["default"].position

    if (page in window.eel._start_geometry.pages) {
      size = window.eel._start_geometry.pages[page].size
      position = window.eel._start_geometry.pages[page].position
    }

    if (size != null) {
      window.resizeTo(size[0], size[1])
    }

    if (position != null) {
      window.moveTo(position[0], position[1])
    }
  },

  createWebSocketConnection: function(dispatch) {
    console.log("createWebSocketConnection() 调用 ")
    if (!window.eel.wsOpened) {
      // 假如请求的Url一开始是这样的: http://localhost:3000/home/dashboard
      let page = window.location.pathname.substring(1)
      // eel._position_window(page);
      // 转换为websocket协议地址
      let websocket_addr = ("http://localhost:9088" + "/eel").replace("http", "ws")
      websocket_addr += "?page=" + page
      // 最终的路径会变成ws://localhost:9088/eel?page=home/dashboard
      window.eel._websocket = new WebSocket(websocket_addr)
      window.eel._websocket.onopen = function(e) {
        console.log("Open Websocket Addr: " + websocket_addr)
        window.eel.wsOpened = true
      }
      window.eel._websocket.onclose = function(e) {
        console.log("websocket onclose: ")
        window.eel.wsOpened = false
      }
      window.eel._websocket.onmessage = function(e) {
        const message = JSON.parse(e.data)
        // console.log("msg",message);
        if (message.hasOwnProperty("deviceStates")) {
          // console.log("states",message);
          dispatch({
            type: "ds/handleDeviceStatesMessage",
            payload: { msg: message.deviceStates }
          })
          // Python making a function call into us
          // if (message.name in window.eel._exposed_functions) {
          //   let return_val = window.eel._exposed_functions[message.name](...message.args);
          //   window.eel._websocket.send(window.eel._toJSON({ return: message.call, value: return_val }));
          // }
        } else if (message.hasOwnProperty("orderStates")) {
          dispatch({
            type: "os/handleOrderStateMessage",
            payload: { msg: message.orderStates }
          })
        } else if (message.hasOwnProperty("alarmInfo")) {
          dispatch({
            type: "ds/handleAlarmInfo",
            payload: { msg: message.alarmInfo }
          })
        } else if (message.hasOwnProperty("rs")) {
          // console.log("states",message);
          dispatch({
            type: "produce/wsHandleRs",
            payload: { msg: message }
          })
        } else if (message.hasOwnProperty("run")) {
          // console.log("states",message);
          dispatch({
            type: "produce/wsHandleRun",
            payload: { msg: message }
          })
        } else if (message.hasOwnProperty("return")) {
          // Python returning a value to us
          console.log("recv msg", message)
          if (message.return in window.eel._call_return_callbacks) {
            window.eel._call_return_callbacks[message.return](message.value)
            delete window.eel._call_return_callbacks[message.return]
          }
        } else if (message.hasOwnProperty("produceState")) {
          dispatch({
            type: "produce/handleProduceMessage",
            payload: { msg: message.produceState }
          })
        } else if (message.hasOwnProperty("settingsUpdate")) {
          dispatch({
            type: "hdst/handleSettingsUpdate"
          })
        } else if (message.hasOwnProperty("cbjZmcToolState")) {
          dispatch({
            type: "cbjt/handleCbjToolMsg",
            payload: { msg: message.cbjZmcToolState }
          })
        } else if (message.hasOwnProperty("lineCamCalState")) {
          dispatch({
            type: "lc/handleLineCamCalMsg",
            payload: { msg: message.lineCamCalState }
          })
        } else if (message.hasOwnProperty("lineCamJointState")) {
          dispatch({
            type: "cj/handleLineCamJointMsg",
            payload: { msg: message.lineCamJointState }
          })
        } else if (message.hasOwnProperty("cutterCamCalState")) {
          dispatch({
            type: "ccc/handleCutterCameraCalMsg",
            payload: { msg: message.cutterCamCalState }
          })
        } else if (message.hasOwnProperty("eapStateUpdate")) {
          dispatch({
            type: "es/handleEapMsgState",
            payload: { msg: message.eapStateUpdate }
          })
        } else {
          throw `Invalid message ${message}`
        }
      }
    }
  }
}
window.oncontextmenu = function(e) {
  //取消默认的浏览器自带右键 很重要！！
  e.preventDefault()
}
